package com.bwda.gateway.filter;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bwda.dsrs.base.centerbase.BaseConstants;
import com.bwda.dsrs.base.centerbase.BaseContextHandler;
import com.bwda.dsrs.base.centerbase.response.ResponseEntity;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
//import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

/**
 * 拦截器，作用所有的微服务
 *
 * @author youzhen
 * @date 2019/5/7
 */
@Configuration
@Slf4j
public class RequestGlobalFilter implements GlobalFilter, Ordered {
    private static final String SPLIT = ",";

    /**
     * 无需校验的url 开头
     */
    @Value("${whiteUrlValue}")
    private String whiteUrlValue;
    @Value("${whiteRefereValue}")
    private String whiteRefereValue;
    @Value("${jwt.pubkey}")
    private String pubkey;
    @Autowired
//    private RedisTemplate redisTemplate;
    @Value("${user_token_expires}")
    private long expireTime;

    /**
     * 登录进入拦截
     */
    @Override
    public Mono<Void> filter(ServerWebExchange serverWebExchange, GatewayFilterChain gatewayFilterChain) {

        ServerHttpRequest request = serverWebExchange.getRequest();
        String requestUri = request.getPath().pathWithinApplication().value();
        BaseContextHandler.setAuthorization(null);
        ServerHttpRequest.Builder mutate = request.mutate();

        // 不进行拦截的地址
        if (isWhiteUrli(requestUri)) {
            log.info("url白名单放行，{}", requestUri);
            ServerHttpRequest build = mutate.build();
            return gatewayFilterChain.filter(serverWebExchange.mutate().request(build).build());
        }


        try {


            List<String> strings = request.getHeaders().get(BaseConstants.AUTHORIZATION);
            String token = null;
            if (strings != null) {
                token = strings.get(0);
            }


            if (StringUtils.isEmpty(token)) {
                log.info("用户Token为空，返回202，requestUri：{}", requestUri);
                return getVoidMono(serverWebExchange, new ResponseEntity("fail", 202, "未登录,请重新登录", Collections.EMPTY_MAP));
            }


//            //先简单校验
//            Object token1 = redisTemplate.opsForValue().get(token);
//            String token2 = token1 == null ? "" : (String) token1;
//            if (StringUtils.isEmpty(token2)) {
//                log.info("redis中用户Token为空，返回202");
//                return getVoidMono(serverWebExchange, new ResponseEntity("fail", 202, "登录超时,请重新登录", Collections.EMPTY_MAP));
//            }
//            //延长有效期
//            redisTemplate.opsForValue().set(token, token);
//            redisTemplate.expire(token, expireTime, TimeUnit.SECONDS);
            mutate.header(BaseConstants.AUTHORIZATION, token);

        } catch (Exception e) {
            log.error("用户Token过期异常", e);
            return getVoidMono(serverWebExchange, new ResponseEntity("fail", 202, "检验出错，请重新登录", Collections.EMPTY_MAP));
        }

        // TODO 判断用户权限,预览编辑等

//        List<PermissionInfo> permissionIfs = userService.getAllPermissionInfo();
        // 判断资源是否启用权限约束
//        Stream<PermissionInfo> stream = getPermissionIfs(requestUri, method, permissionIfs);
//        List<PermissionInfo> result = stream.collect(Collectors.toList());
//        PermissionInfo[] permissions = result.toArray(new PermissionInfo[]{});
//        if (permissions.length > 0) {
//            if (checkUserPermission(permissions, serverWebExchange, user)) {
//                return getVoidMono(serverWebExchange, new TokenForbiddenResponse("User Forbidden!Does not has Permission!"));
//            }
//        }
        // 申请客户端密钥头
//        mutate.header(serviceAuthConfig.getTokenHeader(), serviceAuthUtil.getClientToken());
        ServerHttpRequest build = mutate.build();

//        return getVoidMono(serverWebExchange, new ResponseEntity("fail", 202, "非法token,请重新登录", Collections.EMPTY_MAP));
//
        return gatewayFilterChain.filter(serverWebExchange.mutate().request(build).build());

    }

    @Override
    public int getOrder() {
        return -1000;
    }

    private Mono<Void> getVoidMono(ServerWebExchange serverWebExchange, ResponseEntity body) {
        serverWebExchange.getResponse().setStatusCode(HttpStatus.OK);
        byte[] bytes = JSONObject.toJSONString(body).getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = serverWebExchange.getResponse().bufferFactory().wrap(bytes);



        ServerHttpResponse originalResponse = serverWebExchange.getResponse();
//        originalResponse.setStatusCode(HttpStatus.OK);
        originalResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");

        return originalResponse.writeWith(Flux.just(buffer));





//        return serverWebExchange.getResponse().writeWith(Flux.just(buffer));
    }


    private boolean isWhiteUrli(String requestUri) {
        boolean flag = false;
        for (String s : whiteUrlValue.split(SPLIT)) {
            if (requestUri.startsWith(s)) {
                return true;
            }
        }
        return flag;
    }

}
